package com.tticar.invmanager.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.tticar.invmanager.common.Enum.CodeType;
import com.tticar.invmanager.common.exception.MyServiceException;
import com.tticar.invmanager.common.shiro.MySecurityUtils;
import com.tticar.invmanager.common.utils.date.DateStyle;
import com.tticar.invmanager.common.utils.date.DateUtil;
import com.tticar.invmanager.entity.*;
import com.tticar.invmanager.entity.vo.MyPage;
import com.tticar.invmanager.entity.vo.PurchaseAddDto;
import com.tticar.invmanager.entity.vo.PurchaseGoodsDto;
import com.tticar.invmanager.mapper.PurchaseReturnMapper;
import com.tticar.invmanager.service.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 退货单表 服务实现类
 * </p>
 *
 * @author joeyYan
 * @since 2018-12-21
 */
@Service
public class PurchaseReturnServiceImpl extends ServiceImpl<PurchaseReturnMapper, PurchaseReturn> implements IPurchaseReturnService {

    @Autowired
    private ICodeCounterService codeCounterService;
    @Autowired
    private IOutRepositoryDetailService outRepositoryDetailService;
    @Autowired
    private IRepositoryCountService repositoryCountService;
    @Autowired
    private IPPurchaseService purchaseService;
    @Autowired
    private IPPurchaseDetailService purDetailService;

    @Override
    public Page selectPage(PurchaseReturn purchaseReturn, MyPage<PurchaseReturn> page) {
//        Wrapper wrapper = new EntityWrapper();
        //wrapper.like(Strings.isNotEmpty(purchaseReturn.getName()), PurchaseReturn.NAME, purchaseReturn.getName());
        List<Map> maps = this.baseMapper.queryPurchaseReturnList(page, purchaseReturn);
        page.setRecords(maps);
        return page;
    }
    @Override
    public void delete(List<Long> ids) {
        List list = new ArrayList();
        for (Long id : ids) {
            PurchaseReturn purchaseReturn = new PurchaseReturn();
            purchaseReturn.setId(id);
            purchaseReturn.setStatus(-1);
            list.add(purchaseReturn);
        }
        this.updateBatchById(list);
    }

    @Override
    public List<Map> detailGoodsList(String code) {
        return this.baseMapper.purchaseReturnDetailGoodsList(code);
    }

    /**
     * 新增采购退货单
     * */
    @Override
    @Transactional
    public void addPurchaseReturn(PurchaseAddDto dto) {
        if (dto.getRealPay() == null) {
            dto.setRealPay(BigDecimal.ZERO);
        }
        List<PurchaseGoodsDto> goodsList = dto.getGoodsList();
        Date now = new Date();
        Date outDate = new Date();
        outDate.setHours(0);
        outDate.setMinutes(0);
        outDate.setSeconds(0);
        String ctCode = codeCounterService.getOrderCode(CodeType.CT);
        String ckCode = codeCounterService.getOrderCode(CodeType.CK);
        for (PurchaseGoodsDto goodsDto : goodsList) {
            PurchaseReturn purchaseReturn = new PurchaseReturn();
            purchaseReturn.setCode(ctCode);
            purchaseReturn.setCtime(now);
            purchaseReturn.setRelativeId(dto.getRelativeId());
            purchaseReturn.setCount(goodsDto.getCount());
            purchaseReturn.setSkuId(goodsDto.getSkusId());
            purchaseReturn.setOrderTime(DateUtil.StringToDate(dto.getPtime(), DateStyle.YYYY_MM_DD));
            purchaseReturn.setUnitPrice(new BigDecimal(goodsDto.getAmountActual()));
            purchaseReturn.setUsername(MySecurityUtils.currentUser().getUsername());
            purchaseReturn.setRepositoryStatus(dto.getType() == 0 ? 0 : 1);

            //结算信息
            if (dto.getType() == 0) {
                purchaseReturn.setNeedPay(dto.getRealPay());
            } else {
                purchaseReturn.setPayStatus(0);
                if (dto.getRealPay() != null && dto.getRealPay().compareTo(dto.getTotalMoney()) > -1) {
                    purchaseReturn.setPayStatus(1);
                }
                purchaseReturn.setRealPay(dto.getRealPay());
            }
            purchaseReturn.setRemark(dto.getRemark());
            purchaseReturn.setSettlementStatus(dto.getPayStatus());

            insert(purchaseReturn);

            //如果是生单并出库s
            if (dto.getType() == 1) {
                List<RepositoryCount> repositoryCounts = repositoryCountService.queryOutRepository(goodsDto.getSkusId());
                Integer count = goodsDto.getCount();
                if (repositoryCounts != null && repositoryCounts.size() > 0) {
                    for (RepositoryCount rep : repositoryCounts) {
                        Long wearhouseId = rep.getWearhouseId();
                        Integer num = rep.getCount() > count ? count : rep.getCount();
                        OutRepositoryDetail outRepositoryDetail = new OutRepositoryDetail();
                        outRepositoryDetail.setSkuId(goodsDto.getSkusId());
                        outRepositoryDetail.setCount(num);
                        outRepositoryDetail.setProviderId(dto.getRelativeId());
                        outRepositoryDetail.setType(6);
                        outRepositoryDetail.setWearhouseId(wearhouseId);
                        outRepositoryDetail.setUsername(MySecurityUtils.currentUser().getUsername());
                        outRepositoryDetail.setCode(ckCode);
                        outRepositoryDetail.setBuszId(purchaseReturn.getId());
                        outRepositoryDetail.setOrderTime(outDate);
                        outRepositoryDetail.setRemark(purchaseReturn.getRemark());
                        outRepositoryDetailService.insert(outRepositoryDetail);
                        repositoryCountService.updateRepositoryCount(outRepositoryDetail.getSkuId(), outRepositoryDetail.getWearhouseId(), outRepositoryDetail.getCount() * -1);
                        count = count - rep.getCount();
                        if (count <= 0) {
                            break;
                        }
                    }
                } else {
                    throw new MyServiceException("库存不足，无法出库");
                }
            }
        }


    }

    @Override
    public List<Map> getPurchaseDetailList(String purchaseReturnCode) {

        return this.baseMapper.getPurchaseDetailList(purchaseReturnCode);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void outRepositoryNewVersion(String purchaseReturnCode, List<PurchaseGoodsDto> goodsList,BigDecimal realPay,BigDecimal totalMoney,Integer payStatus,String remark) {
        if (realPay == null) {
            realPay = BigDecimal.ZERO;
        }
        Wrapper wrapper = new EntityWrapper<>();
        wrapper.eq("code",purchaseReturnCode);
        List<PurchaseReturn> purchaseReturns = this.selectList(wrapper);
        Date outDate = new Date();
        outDate.setHours(0);
        outDate.setMinutes(0);
        outDate.setSeconds(0);
        String ckCode = codeCounterService.getOrderCode(CodeType.CK);
        for (PurchaseReturn purchaseReturn : purchaseReturns) {
            for (PurchaseGoodsDto dto : goodsList) {
                if (dto.getSkusId().equals(purchaseReturn.getSkuId())) {
                    purchaseReturn.setRepositoryStatus(1);
                    purchaseReturn.setCount(dto.getCount());
                    purchaseReturn.setUnitPrice(new BigDecimal(dto.getAmountActual().toString()));
                    purchaseReturn.setRealPay(realPay);
                    purchaseReturn.setPayStatus(payStatus);
                    purchaseReturn.setRemark(remark);
                    if (realPay !=null && realPay.compareTo(totalMoney) > -1) {
                        purchaseReturn.setPayStatus(1);
                        purchaseReturn.setNeedPay(BigDecimal.ZERO);
                    } else {
                        purchaseReturn.setNeedPay(totalMoney.subtract(realPay));
                    }
                    this.updateById(purchaseReturn);
                    List<RepositoryCount> repositoryCounts = repositoryCountService.queryOutRepository(dto.getSkusId());
                    Integer count = dto.getCount();
                    Integer totalCount = 0;
                    if (repositoryCounts != null && repositoryCounts.size() > 0) {
                        for (RepositoryCount rep : repositoryCounts) {
                            Long wearhouseId = rep.getWearhouseId();
                            Integer num = rep.getCount() > count ? count : rep.getCount();
                            OutRepositoryDetail outRepositoryDetail = new OutRepositoryDetail();
                            outRepositoryDetail.setSkuId(dto.getSkusId());
                            outRepositoryDetail.setCount(num);
                            outRepositoryDetail.setProviderId(purchaseReturn.getRelativeId());
                            outRepositoryDetail.setType(6);
                            outRepositoryDetail.setUsername(MySecurityUtils.currentUser().getUsername());
                            outRepositoryDetail.setWearhouseId(wearhouseId);
                            outRepositoryDetail.setCode(ckCode);
                            outRepositoryDetail.setBuszId(purchaseReturn.getId());
                            outRepositoryDetail.setOrderTime(outDate);
                            outRepositoryDetail.setRemark(purchaseReturn.getRemark());
                            outRepositoryDetailService.insert(outRepositoryDetail);
                            repositoryCountService.updateRepositoryCount(outRepositoryDetail.getSkuId(), outRepositoryDetail.getWearhouseId(), outRepositoryDetail.getCount() * -1);
                            count = count - rep.getCount();
                            totalCount += num;
                            if (count <= 0) {
                                break;
                            }

                        }
                    } else {
                        throw new MyServiceException("库存不足，无法出库");
                    }
                    if (totalCount < dto.getCount()) {
                        throw new MyServiceException("库存不足，无法出库");
                    }
                }
            }
        }

    }

    @Override
    @Transactional
    public void cancelOutRepository(String purchaseReturnCode) {
        Wrapper wrapper = new EntityWrapper<>();
        wrapper.eq("code", purchaseReturnCode);
        List<PurchaseReturn> purchaseReturns = selectList(wrapper);
        List idList = new ArrayList<>();
        for (PurchaseReturn entity : purchaseReturns) {
            entity.setRepositoryStatus(0);
            entity.setPayStatus(0);
            entity.setNeedPay(entity.getRealPay());
            entity.setRealPay(BigDecimal.ZERO);
            idList.add(entity.getId());
        }
        updateBatchById(purchaseReturns);

        Wrapper wrapper1 = new EntityWrapper<>();
        wrapper1.eq("type", 6);
        wrapper1.in("busz_id", idList);
        wrapper1.eq("status", 0);
        List<OutRepositoryDetail> outRepositoryDetails = outRepositoryDetailService.selectList(wrapper1);
        for (OutRepositoryDetail outRepositoryDetail : outRepositoryDetails) {
            outRepositoryDetail.setStatus(-1);
            repositoryCountService.updateRepositoryCount(outRepositoryDetail.getSkuId(), outRepositoryDetail.getWearhouseId(), outRepositoryDetail.getCount());
        }
        outRepositoryDetailService.updateBatchById(outRepositoryDetails);

    }

    @Override
    public void cancelEndCount(String purchaseReturnCode) {
        Wrapper wrapper = new EntityWrapper<>();
        wrapper.eq("code", purchaseReturnCode);
        List<PurchaseReturn> purchaseReturns = selectList(wrapper);
        for (PurchaseReturn entity : purchaseReturns) {
            entity.setPayStatus(0);
            entity.setRealPay(BigDecimal.ZERO);
        }
        updateBatchById(purchaseReturns);
    }

    /**
     * 结算
     * */
    @Override
    public void endCountPurchaseReturn(String purchaseReturnCode, BigDecimal realPay, BigDecimal totalMoney, Integer payStatus, String remark) {
        Wrapper wrapper = new EntityWrapper<>();
        wrapper.eq("code", purchaseReturnCode);
        List<PurchaseReturn> purchaseReturns = selectList(wrapper);
        for (PurchaseReturn purchaseReturn : purchaseReturns) {
            purchaseReturn.setPayStatus(1);
//            if (realPay.compareTo(totalMoney) >= 0) {
//                purchaseReturn.setPayStatus(1);
//            }
//            purchaseReturn.setRemark(remark);
            purchaseReturn.setRealPay(totalMoney);
            purchaseReturn.setNeedPay(BigDecimal.ZERO);
        }

        this.updateBatchById(purchaseReturns);
    }

    /**
     * 根据采购单进行整单退货
     * */
    @Override
    @Transactional
    public String allReturn(Long id) {
        PPurchase pPurchase = purchaseService.selectById(id);
        if (pPurchase.getOrderStatus() == 3) {
            throw new MyServiceException("此单已退货，请勿重复退货");
        }
        Wrapper wrapper = new EntityWrapper<>();
        wrapper.eq("purchase_id", id);
        String orderCode = codeCounterService.getOrderCode(CodeType.CT);
        pPurchase.setOrderStatus(3);
        pPurchase.setReturnOrder(orderCode);
        purchaseService.updateById(pPurchase);
        List<PPurchaseDetail> pPurchaseDetails = purDetailService.selectList(wrapper);
        for (PPurchaseDetail pPurchaseDetail : pPurchaseDetails) {
            PurchaseReturn purchaseReturn = new PurchaseReturn();
            purchaseReturn.setRelativeId(pPurchase.getRelativeId());
            purchaseReturn.setCode(orderCode);
            purchaseReturn.setCount(pPurchaseDetail.getCount());
            purchaseReturn.setUnitPrice(pPurchaseDetail.getAmountActual());
            purchaseReturn.setOrderTime(new Date());
            purchaseReturn.setPayStatus(0);
            purchaseReturn.setRepositoryStatus(0);
            purchaseReturn.setSkuId(pPurchaseDetail.getSkuId());
            purchaseReturn.setUsername(MySecurityUtils.currentUser().getUsername());
            insert(purchaseReturn);
        }
        return orderCode;
    }

}
